from random import randint
from math import *
from time import time
from pygame import mixer
class weapon:
	def __init__(self, canvas, player, zombies, buildings, shot_array):
		self.canvas = canvas
		self.player = player
		self.zombies = zombies
		self.buildings = buildings
		self.shot_array = shot_array
class chainsaw(weapon):
	type = 'chainsaw'
	def __init__(self, canvas, player, zombies, buildings, shot_array):
		weapon.__init__(self, canvas, player, zombies, buildings, shot_array)
		
		self.color="#999"
		self.x1 = self.player.x
		self.y1 = self.player.y
		
		self.length = 5
		self.timeout = time()
		
		if self.player.direction == "left":
			self.angle = 180
		elif self.player.direction == "up":
			self.angle = 270
		elif self.player.direction == "right":
			self.angle = 0
		else:
			self.angle = 90
		
		self.radians = radians(self.angle)
			
		self.x1 = self.player.x
		self.y1 = self.player.y
			
		x2 = int(cos(self.radians)*self.length)+self.x1
		y2 = int(sin(self.radians)*self.length)+self.y1
			
		self.line = self.canvas.create_line(self.x1,self.y1,x2,y2,width=2,fill=self.color)
		
		self.init_angle = self.angle
		self.angle += 30
	def update(self):
		if self.angle >= 360:
			self.angle -= 360
		if self.init_angle == self.angle:
			self.canvas.delete(self.line)
			if self.timeout < time():
				if hasattr(self,"shot_array"):
					try:
						self.shot_array.remove(self)
					except:
						#... I really don't care if this fails.
						oh_well = True
		else:
			sound = mixer.Sound("chainsaw.ogg")
			sound.set_volume(.5)
			sound.play(0,300)
			self.radians = radians(self.angle)
			
			self.x1 = self.player.x
			self.y1 = self.player.y
			
			x2 = int(cos(self.radians)*self.length)+self.x1
			y2 = int(sin(self.radians)*self.length)+self.y1
			
			self.canvas.delete(self.line)
			self.line = self.canvas.create_line(self.x1,self.y1,x2,y2,width=2,fill=self.color)
			for i in range(self.length):
				xnew = int(cos(self.radians)*i)+self.x1
				ynew = int(sin(self.radians)*i)+self.y1
				for zombie in self.zombies:
					this_distance = sqrt(((xnew-zombie.x)**2)+((ynew-zombie.y)**2))
					if this_distance <= self.length:
						zombie.canvas.delete(zombie.rectangle)
						self.zombies.remove(zombie)
						del zombie
						self.player.score += 25
			self.timeout = time()+1
			self.angle += 30
		
class fire_shot(weapon):
	type = 'fire'
	def __init__(self, canvas, player, zombies, buildings, shot_array):
		weapon.__init__(self, canvas, player, zombies, buildings, shot_array)
		
		self.colors = ['#f01515','#f07715','#f0af15','#edf015']
		
		self.initx = self.player.x
		self.inity = self.player.y
		
		self.x = self.player.x
		self.y = self.player.y
		
		self.rectangle = self.canvas.create_rectangle(self.initx-1,self.inity-1,self.initx+1,self.inity+1,fill=self.colors[randint(0,3)],outline='')
		self.init_vel = self.player.direction
	def update(self):
		for building in self.buildings:
			if building.hit_test(self.x,self.y):
				if hasattr(self,"shot_array"):
					try:
						self.shot_array.remove(self)
					except:
						#... I really don't care if this fails.
						oh_well = True
				self.canvas.delete(self.rectangle)
				
		if self.init_vel == 'up':
			yvel = -1;
			xvel = randint(-1,1)
		elif self.init_vel == 'left':
			yvel = randint(-1,1)
			xvel = -1;
		elif self.init_vel == 'right':
			yvel = randint(-1,1)
			xvel = 1;
		else:
			yvel = 1;
			xvel = randint(-1,1)
		self.canvas.move(self.rectangle,xvel,yvel)
		
		self.x = self.x+xvel
		self.y = self.y+yvel
		
		for zombie in self.zombies:
			this_distance = sqrt(((self.x-zombie.x)**2)+((self.y-zombie.y)**2))
			if this_distance <= 2:
				zombie.canvas.delete(zombie.rectangle)
				self.zombies.remove(zombie)
				del zombie
				self.player.score += 25
		traveled = sqrt(((self.x-self.initx)**2)+((self.y-self.inity)**2))
		
		if traveled > 20:
			self.canvas.delete(self.rectangle)
			if hasattr(self,"shot_array"):
				try:
					self.shot_array.remove(self)
				except:
					#... I really don't care if this fails.
					oh_well = True
class pistol_shot(weapon):
	type = 'pistol'
	def __init__(self, canvas, player, zombies, buildings, shot_array):
		weapon.__init__(self, canvas, player, zombies, buildings, shot_array)
		
		self.color = '#999'
		
		self.initx = self.player.x
		self.inity = self.player.y
		
		self.x = self.player.x
		self.y = self.player.y
		
		self.rectangle = self.canvas.create_rectangle(self.initx-1,self.inity-1,self.initx+1,self.inity+1,fill=self.color,outline='')
		self.init_vel = self.player.direction
	def update(self):
		for building in self.buildings:
			if building.hit_test(self.x,self.y):
				if hasattr(self,"shot_array"):
					try:
						self.shot_array.remove(self)
					except:
						#... I really don't care if this fails.
						oh_well = True
				self.canvas.delete(self.rectangle)
				
		if self.init_vel == 'up':
			yvel = -5
			xvel = 0
		elif self.init_vel == 'left':
			yvel = 0
			xvel = -5
		elif self.init_vel == 'right':
			yvel = 0
			xvel = 5
		else:
			yvel = 5
			xvel = 0
		self.canvas.move(self.rectangle,xvel,yvel)
		
		self.x = self.x+xvel
		self.y = self.y+yvel
		
		for zombie in self.zombies:
			this_distance = sqrt(((self.x-zombie.x)**2)+((self.y-zombie.y)**2))
			if this_distance <= 3:
				zombie.canvas.delete(zombie.rectangle)
				self.zombies.remove(zombie)
				del zombie
				self.player.score += 25
		traveled = sqrt(((self.x-self.initx)**2)+((self.y-self.inity)**2))
class shotgun_shot(weapon):
	type = 'shotgun'
	total_shot = 6
	def __init__(self, canvas, player, zombies, buildings, shot_array):
		weapon.__init__(self, canvas, player, zombies, buildings, shot_array)
		
		self.rectangles = []
		self.xvals = []
		self.yvals = []
		self.xvels = []
		self.yvels = []
		self.keys = []
		
		self.color = '#999'
		
		self.initx = self.player.x
		self.inity = self.player.y
		for i in range(self.total_shot):
			self.keys.append(i)
			self.rectangles.append(self.canvas.create_rectangle(self.initx-1,self.inity-1,self.initx+1,self.inity+1,fill=self.color,outline=''))
			self.yvals.append(self.inity)
			self.xvals.append(self.initx)
			if self.player.direction == 'up':
				self.yvels.append(-5)
				self.xvels.append(randint(-5,5))
			elif self.player.direction == 'left':
				self.xvels.append(-5)
				self.yvels.append(randint(-5,5))
			elif self.player.direction == 'right':
				self.xvels.append(5)
				self.yvels.append(randint(-5,5))
			else:
				self.yvels.append(5)
				self.xvels.append(randint(-2,2))
	def update(self):
		if self.total_shot == 0:
			if hasattr(self,"shot_array"):
				for r in self.rectangles:
					self.canvas.delete(r)
				try:
					self.shot_array.remove(self)
				except:
					#... I really don't care if this fails.
					oh_well = True
		iter = 0
		while iter < len(self.keys):
		
			i = self.keys[iter]
			self.canvas.move(self.rectangles[i],self.xvels[i],self.yvels[i])
			self.xvals[i] = self.xvals[i]+self.xvels[i]
			self.yvals[i] = self.yvals[i]+self.yvels[i]
			broken = False
			
			for building in self.buildings:
				if building.hit_test(self.xvals[i],self.yvals[i]):
					self.canvas.delete(self.rectangles[i])
					self.keys.pop(iter)
					self.total_shot -= 1
					break
					broken = True
					#print self.keys
					
			if not broken and self.xvals[i] > 600 or self.xvals[i] < 0 or self.yvals[i] > 400 or self.yvals[i] < 0:
				if len(self.keys) > iter:
					self.canvas.delete(self.rectangles[i])
					self.keys.pop(iter)
					self.total_shot -= 1
					broken = True
			if not broken:
				for zombie in self.zombies:
					this_distance = sqrt(((self.xvals[i]-zombie.x)**2)+((self.yvals[i]-zombie.y)**2))
					if this_distance <= 2:
						#print len(self.keys)
						#print iter
						if len(self.keys) > iter:
							zombie.canvas.delete(zombie.rectangle)
							self.zombies.remove(zombie)
							del zombie
							self.player.score += 25
							self.canvas.delete(self.rectangles[i])
							self.keys.pop(iter)
							self.total_shot -= 1
							broken = True
			if broken:
				break
				
			iter += 1